/*
 * 观察者模式可能是我们在软件开发中使用得比较多的一种设计模式。
 *
 * 为什么这么说？在windows的软件中，
 *
 * 所有的界都是由窗口构成的。对话框是窗口，菜单是窗口，工具栏也是窗口。
 * 
 * 那么这些窗口，在很多情况下要对一些共有的信息进行处理。
 *
 * 比如说，窗口的放大，窗口的减小等等。面对这一情况，观察者模式就是不错的一个选择。
 *
 * 首先，我们可以对这些共有的object进行提炼。
 */
typedef struct object
{
	observer * pobserver_list[MAX_BINDING_NUMBER];
	int number;

	void (*notify)(struct object * pobject);
	void (*add_observer)(observer * pobserver);
	void (*del_observer)(observer * pobserver);
}object;

/*
 * 其实，我们需要定义的就是观察者本身了。就像我们前面说的一样，
 *
 * 观察者可以是菜单、工具栏或者是子窗口等等
 */
typedef struct observer
{
	object * pobject;

	void (*update)(struct observer * pobserver);
}observer;

/*
 * 紧接着，我们要做的就是在Observer创建的时候，把observer自身绑定到Object上面
 */ 
void bind_observer_to_object(observer * pobserver, object * pobject)
{
	assert(NULL != pobserver && NULL != pobject);

	pobserver->pobject = pobject;
	pobject->add_observer(pobserver);
}

void unbind_observer_from_object(observer * pobserver, object * pobject)
{
	assert(NULL != pobserver && NULL != pobject);

	pobject->del_observer(observer * pobserver);
	memset(pobserver, 0, sizeof(observer));
}

/*
 * 既然Observer在创建的时候就把自己绑定在某一个具体的Object上面，那么Object发生改变的时候，
 *
 * 统一更新操作就是一件很容易的事情了
 */
void notify(struct object * pobject)
{
	obserer * pobserver;
	int index;

	assert(NULL != pobject);
	for (index = 0; index < pobject->number; index++) {
		pobserver = pobject->pobserver_list[index];
		pobserver->update(pobserver);
	}
}